﻿using System;
using RayDen.Library.Core.Primitives;
using RayDen.Library.Data.Imaging;
using RayDen.Library.Entity.Scene;

namespace RayDen.RayEngine.Core.Interface
{
    public enum EmissionDirectionType
    {
        Diffuse,
        Fixed,
        Texture,
    }

    [Flags]
    public enum ProfileMode
    {
        EmissionValue = 0,
        EmissionTexture = 1,
        GoniometricTexture = 2,
    }


    public class EmissionProfile
    {
        public ProfileMode ProfileMode;
        public EmissionDirectionType DirectionalType;

        public string Name, SpdFile;
        public ITexture EmissionTexture;
        public bool InvertTexture;
        public float[] EmissionSpectra;
        public bool SpectralRendering;

        private ISpectrum sspd;

        private RgbSpectrumInfo spd;
        public ISpectrum Evaluate(float u, float v)
        {
            if (SpectralRendering)
            {
                if (EmissionTexture != null)
                    return ColorFactory.FromRgb(EmissionTexture.Sample(u, v), SpectrumType.Illuminant);
                if (EmissionSpectra.Length == 3)
                    return ColorFactory.FromRgb(new RgbSpectrumInfo(EmissionSpectra), SpectrumType.Illuminant);
                return sspd ?? (sspd = new SampledSpectrum(EmissionSpectra));
            }
            else
            {
                if (EmissionTexture != null)
                {
                    return InvertTexture ? (RgbSpectrumInfo.UnitSpectrum() - EmissionTexture.Sample(u, v)) : EmissionTexture.Sample(u, v);
                }
                if (spd == null || spd.IsBlack())
                    spd = getSpectrum();

                return spd;
            }
        }

        private RgbSpectrumInfo getSpectrum()
        {
            if (EmissionSpectra.Length > 3)
            {
                var c = new SampledSpectrum(EmissionSpectra);
                return ColorFactory.SSEToRgbInfo(ref c); 
            }

            return new RgbSpectrumInfo(EmissionSpectra);
        }

        public EmissionProfile(string spdFile)
        {
            EmissionSpectra = SPD_Data.FromSampled(SPD_Data.FromFile(spdFile),
                                             SpectrumType.Illuminant).ToArray();
            this.SpdFile = spdFile;
            ProfileMode = ProfileMode.EmissionValue;
        }


        public EmissionProfile()
        {
            EmissionSpectra = new float[0];
            ProfileMode = ProfileMode.EmissionValue;
        }

    }
}